package com.enterpriseDigitalPlatform.util;


import com.enterpriseDigitalPlatform.anotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class TreeUtil {

    public static <T> Collection<T> buildTree(Collection<T> collection, Integer id) {
        if (collection == null || collection.isEmpty()) {
            return null;
        }
        Collection<T> trees = new ArrayList<>(collection.size());
        Iterator<T> iterator = collection.iterator();

        try {
            Class<?> clazz = null;
            Field[] fields = null;
            while (iterator.hasNext()) {
                T tree = iterator.next();
                if (clazz == null) {
                    clazz = tree.getClass();
                    fields = clazz.getDeclaredFields();
                }
                Field parentIdField = getFieldByAnnotation(fields, TreeParentId.class);
                if (parentIdField != null) {
                    Integer parentIdValue = (Integer) parentIdField.get(tree);
                    if (parentIdValue.equals(id)) {
                        trees.add(tree);
                        iterator.remove();
                    }
                } else {
                    throw new IllegalStateException("未找到父类Id注解");
                }
            }
            if (trees.isEmpty()) {
                return null;
            }
            for (T tree : trees) {
                Field listField = getFieldByAnnotation(fields, TreeList.class);
                Field idField = getFieldByAnnotation(fields, TreeId.class);
                if (listField == null) {
                    throw new IllegalStateException("未找到集合注解");
                }
                if (idField == null) {
                    throw new IllegalStateException("未找到Id注解");
                }
                listField.setAccessible(true);
                listField.set(tree, buildTree(collection, (Integer) idField.get(tree)));
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException("反射访问失败", e);
        }
        return trees;
    }

    // 获取注解对应的字段
    private static Field getFieldByAnnotation(Field[] fields, Class<? extends Annotation> annotationClass) {
        for (Field field : fields) {
            if (field.isAnnotationPresent(annotationClass)) {
                field.setAccessible(true);
                return field;
            }
        }
        return null;
    }

    public static <T> T buildParName(Collection<T> collection, Integer pid, T par) {
        if (collection == null || collection.isEmpty() || pid.equals(0)) {
            return par;
        }
        Iterator<T> iterator = collection.iterator();
        try {
            // 获取集合中第一个元素的类信息和其声明的字段
            Class<?> clazz = collection.iterator().next().getClass();
            Field[] fields = clazz.getDeclaredFields();
            // 直接在声明时尝试获取注解标记的字段，减少中间变量
            Field nameField = getFieldByAnnotation(fields, TreeName.class);
            if (nameField == null) {
                throw new IllegalStateException("未找到名称注解");
            }
            Field parentIdField = getFieldByAnnotation(fields, TreeParentId.class);
            if (parentIdField == null) {
                throw new IllegalStateException("未找到父类Id注解");
            }
            Field idField = getFieldByAnnotation(fields, TreeId.class);
            if (idField == null) {
                throw new IllegalStateException("未找到Id注解");
            }
            Field parNameField = getFieldByAnnotation(fields, TreeParentName.class);
            if (parNameField == null) {
                throw new IllegalStateException("未找到全称注解");
            }
            parNameField.setAccessible(true);
            Field parIdsField = getFieldByAnnotation(fields, TreeParentIds.class);
            if (parIdsField == null) {
                throw new IllegalStateException("未找到全称IdArr注解");
            }
            parIdsField.setAccessible(true);
            while (iterator.hasNext()) {
                T item = iterator.next();
                Integer idValue = (Integer) idField.get(item);
                Integer parentIdValue = (Integer) parentIdField.get(item);
                String nameValue = (String) nameField.get(item);
                if (idValue.equals(pid)) {
                    parNameField.set(par, nameValue + "-" + parNameField.get(par));
                    parIdsField.set(par, idValue + "-" + parIdsField.get(par));
                    if (parentIdValue.equals(0)) {
                        return par;
                    }
                    return buildParName(collection, parentIdValue, par);
                }
            }
            return par;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> ArrayList<Integer> getChildId(Collection<T> collection, Integer id, ArrayList<Integer> childrens) {
        if (collection == null || collection.isEmpty()) {
            return childrens;
        }
        Iterator<T> iterator = collection.iterator();
        try {
            // 获取集合中第一个元素的类信息和其声明的字段
            Class<?> clazz = collection.iterator().next().getClass();
            Field[] fields = clazz.getDeclaredFields();
            Field parentIdField = getFieldByAnnotation(fields, TreeParentId.class);
            if (parentIdField == null) {
                throw new IllegalStateException("未找到父类Id注解");
            }
            Field idField = getFieldByAnnotation(fields, TreeId.class);
            if (idField == null) {
                throw new IllegalStateException("未找到Id注解");
            }
            while (iterator.hasNext()) {
                T item = iterator.next();
                Integer idValue = (Integer) idField.get(item);
                Integer parentIdValue = (Integer) parentIdField.get(item);
                if (parentIdValue.equals(id)) {
                    childrens.add(idValue);
                    childrens = getChildId(collection, idValue, childrens);
                }
            }
            return childrens;
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
